package yc.tool.dbmigrate.service;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import yc.tool.dbmigrate.common.Constant;
import yc.tool.dbmigrate.conf.SyncPropConfigurer;
import yc.tool.dbmigrate.dao.ICommonDao;
import yc.tool.dbmigrate.entity.DbInfo;
import yc.tool.dbmigrate.entity.SyncBean;
import yc.tool.dbmigrate.entity.SyncConfig;
import yc.tool.dbmigrate.exception.SyncConfigException;

@Service
public class MigreateService {
	@Resource(name = "sqlserverDao")
	private ICommonDao sqlserverDao;
	@Resource(name = "oracleDao")
	private ICommonDao oracleDao;
	@Resource(name = "mysqlDao")
	private ICommonDao mysqlDao;

	private final Logger log = LoggerFactory.getLogger(this.getClass());
	
	//真正使用的dao层
	private ICommonDao sourceDao;
	private ICommonDao tagDao;
	
	/**
	 * 初始化主类
	 */
	public void init() {
		System.out.println("初始化MigreateService");
		SyncConfig syncConfig = SyncPropConfigurer.getSyncConfig();
		DbInfo sourceDb = syncConfig.getSourceDb();
		if (null == sourceDb)
			throw new SyncConfigException("无法获取到源数据库信息");
		DbInfo tagDb = syncConfig.getTagDb();
		if (null == tagDb) {
			throw new SyncConfigException("无法获取到目标数据库信息");
		}
		sourceDao = getCommonDaoByDbType(sourceDb.getDbType());
		sourceDao.init();//本工程，service，dao 对象都需要初始化
		tagDao = getCommonDaoByDbType(tagDb.getDbType());
		tagDao.init();
	}
	
	private ICommonDao getCommonDaoByDbType(String dbType) {
		switch(dbType) {
		case "sqlserver":
			return sqlserverDao;
		case "oracle":
			return oracleDao;
        case "mysql":
             return mysqlDao;
		default:
			throw new SyncConfigException("数据库类型不支持:" + dbType);
		}
	}
	
	/**
	 * 数据迁移主方法
	 * @throws Exception 
	 */
	public void dbMigrate() throws Exception {
		Long startTime = System.currentTimeMillis();
		SyncConfig syncConfig = SyncPropConfigurer.getSyncConfig();
		List<SyncBean> syncBeans = syncConfig.getSyncBeans();
		
		int syncStatus = Constant.SYNC_STATUS_FINISH;
		for (SyncBean syncBean : syncBeans) {
			try {
				syncBean.setSyncStatus(Constant.SYNC_STATUS_SYNCING);
				if ("simple".equals(syncBean.getSyncType())) {
					simpleDbMigrate(syncBean);
				} else if ("custom".equals(syncBean.getSyncType())) {
					ICustomSyncService cus = (ICustomSyncService) Class.forName(syncBean.getClassName()).newInstance();
					cus.start();
				}
				syncBean.setSyncStatus(Constant.SYNC_STATUS_FINISH);
			} catch (Exception e) {
				syncStatus = Constant.SYNC_STATUS_FAILED;
				syncBean.setSyncStatus(Constant.SYNC_STATUS_FAILED);
				log.info("模块" + syncBean.getSyncIndex() + "同步失败，请检查日志排除问题后重新同步");
				break;
			}
			
		}
		
		//用时
		Long syncTime = (System.currentTimeMillis()-startTime)/1000;
		log.info("开始记录当前状态...");
		SyncPropConfigurer.archiveSyncStatus(syncStatus, syncTime.intValue());
		
		log.info("同步结束，总共用时：" + syncTime + "秒");
		
	}
	
	/**
	 * 简单数据迁移(一张表)
	 * @param syncBean
	 */
	@Transactional(rollbackFor=Exception.class)
	private void simpleDbMigrate(SyncBean syncBean) throws Exception {
		SyncConfig syncConfig = SyncPropConfigurer.getSyncConfig();
		Integer pageSize = syncConfig.getOther().getPageSize();//分页数
		
		//总页数
		Integer total = sourceDao.tableSize(syncBean.getTableInfo());
		Integer totalPageNumber = (total / pageSize) + 1;
		log.info("开始同步第" + syncBean.getSyncIndex() + "模块, 简单表同步：" + syncBean.getTableInfo().getSourceTableName() + ", 每页" + pageSize + ", 共" + totalPageNumber + "页，总共" + total + "条数据");
		
		//循环查询并插入数据
		for (int i = 0; i < totalPageNumber; i++) {
			List<Map<String, Object>> res = sourceDao.selectOnePageData(syncBean.getTableInfo(), (i+1), pageSize);
			log.info("第" + syncBean.getSyncIndex() + "模块，第" + (i+1) + "/" + totalPageNumber + "页 有" + res.size() + "条数据");
			if (null == res || res.size() == 0) {
				break;
			}
			tagDao.insertDataBat(syncBean.getTableInfo(), res, syncConfig.getSourceDb().getDbType());
			
		}
		
	}
}
